
import { httpDefaultConfig } from '@/service/http-type'
import type { ApiObject, Method, ExConfigParams } from '@/service/http-type'
import { isString, isFunction, isBoolean, isArray } from '@/service/type-utils'
import type { AxiosRequestConfig } from 'axios'
import { axiosCancel } from './helper'
type Config = AxiosRequestConfig & ApiObject

// 默认以axios 配置项config 为基础，且以config中的权限为最高。
export function dealConfigs (urlOrApiObject: string | ApiObject, params?: object, method?: Method, exparams?: Partial<ExConfigParams>): {
  config: Config,
  afterResponse: (res: any) => any
} {
  let cancel = new axiosCancel()
  // config 传入配置项，主要处理传参方式及传参数据；excitedForm 是否formData传参标志位；excitedAfterResponse 自定义额外参数是否有响应回调函数； afterReponse 自定义响应回调函数
  let config = { url: '' } as Config, excitedForm = false ,excitedAfterResponse = false, afterResponse = null
  let result = null

  method ? config['method'] = method : ''

  if(isString(urlOrApiObject)) {
    config.url = urlOrApiObject
  }else {
    config = { ...config, ...urlOrApiObject as ApiObject } as Config

    // beforeFetch，接口请求前钩子，如果为false，取消请求
    const { beforeFetch } = config
    result = beforeFetch && isFunction( beforeFetch ) && beforeFetch( params )
    if( isBoolean(result) && result === false ) return

    if(urlOrApiObject?.headers?.['content-type'] === httpDefaultConfig.formDataContentType || urlOrApiObject?.exparams?.isFormData || exparams?.isFormData) {
      config['data'] = result ?? transFormData(urlOrApiObject?.data || urlOrApiObject?.params || params || {})
      excitedForm = true
      delete config['params']
    }

    if(isFunction(urlOrApiObject?.exparams?.afterReponse)) {
      afterResponse = exparams?.afterReponse
      excitedAfterResponse = true
    }

  }

  if(!excitedAfterResponse && isFunction(exparams?.afterReponse)) {
    afterResponse = exparams?.afterReponse
  }

  // 如果未指定formData、data的传参方式，默认指定为data
  if(!excitedForm) {
    if(config['method'] === 'get') {
      delete config['data']
      config['params'] = result ? {...result, ...params??{}} : {...config['params']??{}, ...params??{}}
    }else {
      delete config['params']
      config['data'] = result ? {...result, ...params??{}} : {...config['data']??{}, ...params??{}}
    }
  }

  cancel.addCancel(config)

  return { config, afterResponse }
}

const transFormData = (param: object): FormData => {
  const formData = new FormData()

  Object.keys(param).forEach(key => {
    if(isArray(param[key])) {
      param[key].map(item => formData.append(param[key], item))
    }else {
      formData.append(key, param[key])
    }
  })
  return formData
}
